package ds

import "errors"

//Bytes uses []byte as bottom data structure, in order to store any type value
type Bytes struct {
	b     []byte
	bType uint8
}

//NewBytes creates a new Bytes stored value, convert value to []byte
func NewBytes(value interface{}) Bytes {
	switch value.(type) {
	case string:
		return Bytes{
			b:     []byte(value.(string)),
			bType: 1,
		}
	case []byte:
		return Bytes{
			b:     value.([]byte),
			bType: 0,
		}
	}

	if value == nil {
		return Bytes{b: nil}
	}

	return Bytes{b: nil}
}

func (v Bytes) Len() int {
	return len(v.b)
}

func (v Bytes) Clone() []byte {
	return CloneBytes(v.b)
}

func (v Bytes) String() (string, error) {
	if v.bType == 1 {
		return string(v.b), nil
	}
	return "", errors.New("can not convert []byte to string, should just return []byte, use Bytes.Byte()")
}

func (v Bytes) Byte() []byte {
	return v.b
}

func CloneBytes(b []byte) []byte {
	c := make([]byte, len(b))
	copy(c, b)
	return c
}
